/*
*	Copyright (c) 2009 Brent Mombourquette
*
*	Permission is hereby granted, free of charge, to any person
*	obtaining a copy of this software and associated documentation
*	files (the "Software"), to deal in the Software without
*	restriction, including without limitation the rights to use,
*	copy, modify, merge, publish, distribute, sublicense, and/or sell
*	copies of the Software, and to permit persons to whom the
*	Software is furnished to do so, subject to the following
*	conditions:
*
*	The above copyright notice and this permission notice shall be
*	included in all copies or substantial portions of the Software.
*
*	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*	OTHER DEALINGS IN THE SOFTWARE.
*
*	This file contains the functions with build the graph from graph_page.html up.
*/

var nodes;

const NEW_ROOT = 0;		// These are the three possibilites which could cause a live update
const NEW_EDGE = 1;		// See liveUpdate() in graph_page.html
const NEW_NODE_AND_EDGE = 2;

var buildGraph = {
	
	/*
	 * Construct the nodes and edges of the graph
	 * Globals: forcesStopped [from graph_page.html], nextRooty [from ForceDirectedLayout.js], nodes
	 * @param {ForceDirectedLayout} layout 
	 */
	makeGraph: function(layout) {
		var maxRow = database.getMaxRow();
		nodes = new Object();
		// Reset the root positions
		nextRootY = -150;
		// Determine if the current graph is a filtered graph
		var filterText = document.getElementById("filteringText").innerHTML;
		var filterSet = filterTab.isFiltered(filterText);

		// The node deletion operation removes rows from the database, so not all indicines may be a valid database entry
		for ( var i = 1; i <= maxRow; i++ ) {
			var entry = database.extractRow(i);
			// Every valid entry has a destination, if there is none present then this row does not exist in the database. 
			if (!entry['destination']){
				continue;
			}
			
			var entryFiltered = false;
			if (filterSet && filterTab.filterMatch(entry['destination'])) {
				entryFiltered = true;
			}
			
			if ( !entryFiltered ) {
				if (nodes[entry['destination']]) { // Do not create multiple copies of the same node
					// Safeguard: a URL that has already been entered into the nodes object yet does not have a source URL is an error
					if(nodes[entry['source']]) {
						var nodeA = nodes[entry['source']];
						var nodeB = nodes[entry['destination']];
						var annotation = entry['ann'];
						// Create the entry in the Session Trail panel for this edge
						sessionTrail.createEntry(entry['title'], entry['timeEnter'], i);
						// The "1" parameter is a binary direction choice for the edge marker's pointing direction, since edges
						// added between pre-existing nodes have to be added in the order (source, destination) in order not to break 
						// the graph when a circuit with a root node is created (Bug in JSViz library)
						layout.newDataGraphEdge(nodeA, nodeB, entry, 1);
					}
					continue;
				}
				
				var node = new DataGraphNode();
				//Set all of the relevant node properties
				node.mass=.5;
				node.url = entry['destination'];
				node.title = entry['title'];
				node.permTitle = entry['permTitle'];
				node.date = entry['timeEnter'];
				node.nodeURLKey = entry['idx'];
				node.fav = entry['fav'];
				node.img = entry['image'];
				
				if (entry['cords'] != "NO_CORDS") {
					var cords = entry['cords'].split(",");
					node.cords = true;
					node.xCord = cords[0];
					node.yCord = cords[1];
				} 
				
				// If the source matches the filtering criteria then make this a root node, since it's parent won't be entered
				if (filterSet && filterTab.filterMatch(entry['source']))
					entry['source'] = 'EMPTY_SOURCE_ENTRY';
				
				if ( entry['source'] == 'EMPTY_SOURCE_ENTRY' || !nodes[entry['source']]) {
					// A root node has no valid source URL
					node.color = '#FF0000';
					node.fixed = true;
					layout.newDataGraphNode( node );
				} else {
					// This is not a root entry so create the entry in the Session Trail panel for this edge
					sessionTrail.createEntry(entry['title'], entry['timeEnter'], i );
					node.color = "#00688B";
					layout.newDataGraphNode( node );
					var neighbor = nodes[entry['source']];
					var annotation = entry['ann'];
					// This is a normal edge so it is entered in the order (destination,source) and has the regular marker direction, 0					
					layout.newDataGraphEdge( node, neighbor, entry, 0);							
				}
				nodes[entry['destination']] = node;		// Keep a dictionary of all the previously added Nodes
			}
		}
	},
	
	/*
	 * Update the graph whenever a new entry is logged. This function does the "Live Updating" feature.
	 * Globals: nodes
	 */
	updateGraph: function() {
		var maxRow = database.getMaxRow();
		
		// Determine if the current graph is a filtered graph
		var filterText = document.getElementById("filteringText").innerHTML;
		var filterSet = filterTab.isFiltered(filterText);
		
		// Safeguard
		if (maxRow) {
			var result = database.extractRow(maxRow);
			
			var entryFiltered = false;
			if (filterSet && filterTab.filterMatch(result['destination'])) {
				entryFiltered = true;
			}
			
			if (!entryFiltered) {
				if (nodes[result['destination']]) { // Do not create multiple copies of the same node
					// Safeguard: a URL that has already been entered into the nodes object yet does not have a source URL is an error
					if(nodes[result['source']]) {
						var nodeA = nodes[result['source']];
						var nodeB = nodes[result['destination']];
						var annotation = result['ann'];
						// Create the entry in the Session Trail panel for this edge
						sessionTrail.createEntry(result['title'], result['timeEnter'], result['idx']);
						// The "1" parameter is a binary direction choice for the edge marker's pointing direction, since edges
						// added between pre-existing nodes have to be added in the order (source, destination) in order not to break 
						// the graph when a circuit with a root node is created (Bug in JSViz library)
						layout.newDataGraphEdge(nodeA, nodeB, result, 1);
						return NEW_EDGE;
					}
					return;
				}
				
				var node = new DataGraphNode();
				//Set all of the relevant node properties
				node.mass=.5;
				node.url = result['destination'];
				node.title = result['title'];
				node.permTitle = result['permTitle'];
				node.date = result['timeEnter'];
				node.nodeURLKey = result['idx'];
				node.fav = result['fav'];
				node.img = result['image'];
				
				// New entry, so it wont have any cords
				
				if (filterSet && filterTab.filterMatch(result['source'])) {
					result['source'] = 'EMPTY_SOURCE_ENTRY';
				}
				
				if ( result['source'] == 'EMPTY_SOURCE_ENTRY') {
					// A root node has no valid source URL
					node.color = '#FF0000';
					node.fixed = true;
					layout.newDataGraphNode( node );
					// Keep track of all of the nodes added
					nodes[result['destination']] = node;
					return NEW_ROOT;
				} else {
					// This is not a root entry so create the entry in the Session Trail panel for this edge
					sessionTrail.createEntry(result['title'], result['timeEnter'], maxRow );
					
					node.color = "#00688B";
					layout.newDataGraphNode( node );
					var neighbor = nodes[result['source']];
					var annotation = result['ann'];
					// This is a normal edge so it is entered in the order (destination,source) and has the regular marker direction, 0
					layout.newDataGraphEdge( node, neighbor, result, 0);
					// Keep track of all the nodes added
					nodes[result['destination']] = node;
					return NEW_NODE_AND_EDGE;
				}
			}
		}
	}
}